package cc.geeksearch.ble

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Face
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import cc.geeksearch.ble.bean.CharacteristicBean
import cc.geeksearch.ble.bean.ServiceBean

class DeviceActivity : ComponentActivity() {
    private val TAG = "DeviceActivity"
    private var address: String? = null
    private var status by mutableIntStateOf(DeviceStatus.NOT_CONNECTED)
    private var remark by mutableStateOf("")
    private val serviceUUIDList = mutableStateListOf<ServiceBean>()

    @SuppressLint("StateFlowValueCalledInComposition")
    @OptIn(ExperimentalMaterial3Api::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        val name = intent.getStringExtra("name")
        address = intent.getStringExtra("address")
        remark = intent.getStringExtra("remark")!!
        status = intent.getIntExtra("status", DeviceStatus.NOT_CONNECTED)
        setContent {
            var showRemark by remember { mutableStateOf(false) }
            Scaffold(
                modifier = Modifier.fillMaxSize(),
                topBar = {
                    TopAppBar(
                        title = {
                            Column {
                                Text(
                                    text = name ?: "N/A",
                                    fontSize = 18.sp
                                )
                            }
                        },
                        colors = TopAppBarDefaults.topAppBarColors(
                            containerColor = MaterialTheme.colorScheme.primaryContainer,
                            titleContentColor = MaterialTheme.colorScheme.primary,
                        ),
                        navigationIcon = {
                            IconButton(onClick = {
                                finish()
                            }) {
                                Icon(
                                    imageVector = Icons.AutoMirrored.Filled.ArrowBack,
                                    contentDescription = stringResource(R.string.back)
                                )
                            }
                        },
                        actions = {
                            when (status) {
                                DeviceStatus.NOT_CONNECTED, DeviceStatus.DISCONNECTED, DeviceStatus.CONNECT_FAILED -> {
                                    IconButton(onClick = {
                                        Walle.getInstance(baseContext).connect(address!!)
                                    }) {
                                        Icon(
                                            imageVector = Icons.Default.PlayArrow,
                                            contentDescription = stringResource(R.string.disconnect)
                                        )
                                    }
                                }

                                DeviceStatus.CONNECTING -> {
                                    val infiniteTransition = rememberInfiniteTransition()
                                    val angle by infiniteTransition.animateFloat(
                                        initialValue = 0f,
                                        targetValue = 360f,
                                        animationSpec = infiniteRepeatable(
                                            animation = tween(1000, easing = LinearEasing)
                                        )
                                    )
                                    IconButton(onClick = {
                                        Walle.getInstance(baseContext).disconnect(address!!)
                                    }) {
                                        Icon(
                                            modifier = Modifier.rotate(angle),
                                            imageVector = Icons.Default.Refresh,
                                            contentDescription = stringResource(R.string.status_connecting)
                                        )
                                    }
                                }

                                DeviceStatus.CONNECTED, DeviceStatus.PREPARED -> {
                                    IconButton(onClick = {
                                        Walle.getInstance(baseContext).disconnect(address!!)
                                    }) {
                                        Icon(
                                            imageVector = Icons.Default.Clear,
                                            contentDescription = stringResource(R.string.disconnect)
                                        )
                                    }
                                }
                            }

                            var expanded by remember { mutableStateOf(false) }


                            IconButton(onClick = { expanded = true }) {
                                Icon(
                                    imageVector = Icons.Default.MoreVert,
                                    contentDescription = stringResource(R.string.more_options)
                                )
                            }
                            DropdownMenu(
                                expanded = expanded,
                                onDismissRequest = { expanded = false }) {
                                DropdownMenuItem(
                                    text = { Text(stringResource(R.string.delete)) },
                                    onClick = {
                                        expanded = false
                                        Walle.getInstance(baseContext).delete(address!!)
                                        finish()
                                    }
                                )

                                DropdownMenuItem(
                                    text = { Text("Log") },
                                    onClick = {
                                        expanded = false
                                        startActivity(
                                            Intent(
                                                baseContext,
                                                LogActivity::class.java
                                            ).apply {
                                                putExtra("address", address)
                                            })
                                    }
                                )
                                if(status > DeviceStatus.CONNECTED){
                                    DropdownMenuItem(
                                        text = { Text("Remark") },
                                        onClick = {
                                            expanded = false
                                            showRemark = true
                                        }
                                    )
                                }
                            }
                        }
                    )
                }) { innerPadding ->
                LoadService(
                    context = baseContext,
                    address = address,
                    status = status,
                    serviceUUIDList = serviceUUIDList,
                    modifier = Modifier.padding(innerPadding)
                )
                if (showRemark) {
                    ShowRemarkDialog(
                        baseContext,
                        address!!,
                        remark!!,
                        onDismiss = { showRemark = false })
                }
            }
        }

        LiveDataBus.deviceStatusLiveData.observe(this) {
            if (it.address != address) {
                return@observe
            }
            status = it.status
            remark = it.remark
            if (status == DeviceStatus.PREPARED && serviceUUIDList.isEmpty()) {
                Walle.getInstance(baseContext).getServiceUUIDS(address!!)
            } else if (status == DeviceStatus.DISCONNECTED) {
                serviceUUIDList.clear()
            }
        }

        LiveDataBus.uuidLiveData.observe(this) { item ->
            if (item.isEmpty()) {
                return@observe
            }
            val service = item[address]
            if (service != null) {
                serviceUUIDList.clear()
                serviceUUIDList.addAll(service)
            }
        }
    }

    override fun onStart() {
        super.onStart()
        Walle.getInstance(baseContext).getServiceUUIDS(address!!)
    }
}


@Composable
fun LoadService(
    context: Context,
    address: String?,
    status: Int,
    serviceUUIDList: MutableList<ServiceBean>,
    modifier: Modifier = Modifier
) {
    val scrollState = rememberScrollState()
    Column(
        modifier = modifier
            .fillMaxWidth()
            .verticalScroll(scrollState),
    ) {
        Box(
            modifier = Modifier
                .padding(10.dp)
                .fillMaxWidth()
        ) {
            val connectStatusName = when (status) {
                DeviceStatus.CONNECTED -> stringResource(R.string.status_connected)
                DeviceStatus.CONNECTING -> stringResource(R.string.status_connecting)
                DeviceStatus.PREPARED -> stringResource(R.string.status_prepared)
                DeviceStatus.DISCONNECTED -> stringResource(R.string.status_disconnected)
                DeviceStatus.CONNECT_FAILED -> stringResource(R.string.status_failed)
                else -> stringResource(R.string.status_not_connected)
            }
            Text(
                text = address ?: "N/A",
                fontSize = 14.sp,
                color = MaterialTheme.colorScheme.tertiary,
                modifier = Modifier.align(Alignment.TopStart)
            )
            Text(
                text = connectStatusName,
                fontSize = 14.sp,
                modifier = Modifier.align(Alignment.TopEnd)
            )
        }

        serviceUUIDList.forEach { service ->
            var isExpanded by remember { mutableStateOf(false) }
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(10.dp)
                    .clickable {
                        isExpanded = !isExpanded
                    }
            ) {
                Text(
                    text = "Service",
                    fontSize = 18.sp,
                )
                Row {
                    Text(
                        text = "UUID:",
                        fontSize = 14.sp,
                        color = MaterialTheme.colorScheme.tertiary,
                        modifier = Modifier.padding(top = 5.dp),
                    )
                    Text(
                        text = service.uuid,
                        fontSize = 14.sp,
                        modifier = Modifier.padding(top = 5.dp),
                    )
                }
            }
            androidx.compose.material3.HorizontalDivider(
                thickness = 0.5.dp
            )
            if (isExpanded) {
                service.characteristics.forEach { characteristic ->
                    LoadCharacteristic(
                        context = context,
                        address = address!!,
                        serviceUUID = service.uuid,
                        characteristicBean = characteristic,
                    )
                }
            }
        }
    }
}


@SuppressLint("UnrememberedMutableState")
@Composable
fun LoadCharacteristic(
    context: Context,
    address: String,
    serviceUUID: String,
    characteristicBean: CharacteristicBean
) {
    var showDialog by remember { mutableStateOf(false) }
    // 已订阅
    // var subscribed by remember { mutableStateOf(false) }

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(5.dp)
    ) {
        Box(
            modifier = Modifier.fillMaxWidth()
        ) {
            Text(
                text = "Characteristic",
                fontSize = 16.sp,
                modifier = Modifier
                    .padding(start = 10.dp)
                    .align(androidx.compose.ui.Alignment.CenterStart),
            )
            Row(
                modifier = Modifier.align(androidx.compose.ui.Alignment.CenterEnd)
            ) {
                if (characteristicBean.isNotify) {
                    val color =
                        if (characteristicBean.subscribed) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.tertiary
                    Icon(
                        imageVector = Icons.Default.Notifications,
                        contentDescription = "Notification Icon",
                        tint = color,
                        modifier = Modifier
                            .padding(10.dp)
                            .clickable {
                                if (characteristicBean.subscribed) {
                                    Walle.getInstance(context)
                                        .unsubscribe(address, serviceUUID, characteristicBean.uuid)
                                } else {
                                    Walle.getInstance(context)
                                        .subscribe(address, serviceUUID, characteristicBean.uuid)
                                }
                            }
                    )
                }
                if (characteristicBean.isRead) {
                    Icon(
                        imageVector = Icons.Default.Face,
                        contentDescription = "Read Icon",
                        modifier = Modifier
                            .padding(10.dp)
                            .clickable {
                                Walle.getInstance(context)
                                    .read(address, serviceUUID, characteristicBean.uuid)
                            }
                    )
                }
                if (characteristicBean.isWrite) {
                    Icon(
                        imageVector = Icons.Default.Send,
                        contentDescription = "Write Icon",
                        modifier = Modifier
                            .padding(10.dp)
                            .clickable {
                                showDialog = true
                            }
                    )
                }
            }
        }
        Row(
            modifier = Modifier.padding(top = 5.dp, start = 10.dp),
        ) {
            Text(
                text = "UUID:",
                fontSize = 13.sp,
                color = MaterialTheme.colorScheme.tertiary,
            )
            Text(
                text = characteristicBean.uuid,
                fontSize = 13.sp
            )
        }
        Row(
            modifier = Modifier.padding(top = 5.dp, start = 10.dp)
        ) {
            Text(
                text = "Properties:",
                fontSize = 13.sp,
                color = MaterialTheme.colorScheme.tertiary,
            )
            var permissions = ""
            if (characteristicBean.isRead) {
                permissions += " Read"
            }
            if (characteristicBean.isWrite) {
                permissions += " Write"
            }
            if (characteristicBean.isNotify) {
                permissions += " Notify"
            }
            if (permissions.isNotEmpty()) {
                Text(
                    text = permissions.substring(1),
                )
            }
        }
    }
    if (showDialog) {
        ShowWriteDialog(
            context,
            address,
            serviceUUID,
            characteristicBean,
            onDismiss = { showDialog = false })
    }
}

/**
 * 弹出一个输入框，输入数据发送给设备
 *
 */
@SuppressLint("UnrememberedMutableState")
@Composable
fun ShowWriteDialog(
    context: Context,
    address: String,
    serviceUUID: String,
    characteristicBean: CharacteristicBean,
    onDismiss: () -> Unit
) {
    var text by mutableStateOf("")
    AlertDialog(
        onDismissRequest = {
            onDismiss()
        },
        title = {
            Text(text = stringResource(R.string.send_data))
        },
        text = {
            TextField(
                // 过滤输入，只保留十六进制字符
                value = text.filter { it in '0'..'9' || it in 'a'..'f' || it in 'A'..'F' },
                onValueChange = { newText ->
                    text = newText.filter { it in '0'..'9' || it in 'a'..'f' || it in 'A'..'F' }
                },
                label = { Text(stringResource(R.string.input_hex_context)) },
                singleLine = false,
                maxLines = 5
            )
        },
        confirmButton = {
            Button(
                onClick = {
                    if (text.isNotBlank()) {
                        onDismiss()
                        // WalleLog.d(TAG ,"发送内容：$text")
                        val bytes = text.chunked(2).map { it.toInt(16).toByte() }.toByteArray()
                        Walle.getInstance(context)
                            .sendData(address, serviceUUID, characteristicBean.uuid, bytes)
                    }
                }
            ) {
                Text(stringResource(R.string.send))
            }
        },
        dismissButton = {
            Button(
                onClick = {
                    onDismiss()
                }
            ) {
                Text(stringResource(R.string.cancel))
            }
        }
    )
}

@SuppressLint("UnrememberedMutableState")
@Composable
fun ShowRemarkDialog(
    context: Context,
    address: String,
    remark: String,
    onDismiss: () -> Unit
) {
    var text by mutableStateOf(remark)
    AlertDialog(
        onDismissRequest = {
            onDismiss()
        },
        title = {
            Text(text = "Remark")
        },
        text = {
            TextField(
                value = text,
                onValueChange = { newText ->
                    text = newText
                },
                label = { Text("Remark name") },
                singleLine = true
            )
        },
        confirmButton = {
            Button(
                onClick = {
                    if (text.isNotBlank()) {
                        onDismiss()
                        Walle.getInstance(context).remark(
                            address,
                            text
                        )
                    }
                }
            ) {
                Text(stringResource(R.string.send))
            }
        },
        dismissButton = {
            Button(
                onClick = {
                    onDismiss()
                }
            ) {
                Text(stringResource(R.string.cancel))
            }
        }
    )
}


@Preview(showBackground = true)
@Composable
fun LoadServicePreview() {
    /* WalleBleKitTheme {
         Greeting(DeviceStatus.CONNECTED)
     }*/
}